package com.extremelylargepackage;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

import com.extremelylargepackage.entity.Enemy;
import com.extremelylargepackage.entity.Player;

import android.content.Context;
import android.util.Log;

public class GameStateSaver {
	private PrintWriter _output;
	private Context _context;

	public GameStateSaver(Context context) {
		_context = context;
		try {
			_output = new PrintWriter(new BufferedOutputStream(context.openFileOutput("gamestate", Context.MODE_PRIVATE)));
			_output.println("<gameState>");
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();
		}
	}

	/**
	 * Writes a player state representation to the output.
	 * 
	 * @param playerState
	 */
	public void writePlayer(Map<String, Object> playerState) {
		_output.println("<player>");
		writeStateObjects(playerState);
		_output.println("</player>");
	}

	/**
	 * Writes an enemy state representation to the output.
	 * 
	 * @param enemyState
	 */
	public void writeEnemy(Map<String, Object> enemyState)
	{
		_output.println("<enemy>");
		writeStateObjects(enemyState);
		_output.println("</enemy>");
	}

	public void writeScenery(Map<String, Object> sceneryState)
	{
		_output.println("<scenery>");
		writeStateObjects(sceneryState);
		_output.println("</scenery>");
	}


	/**
	 * Writes all state information given in <i>state</i> to the output file.
	 * 
	 * @param state
	 */
	private void writeStateObjects(Map<String, Object> state)
	{
		for(Map.Entry<String, Object> stateEntry : state.entrySet()) {
			String key = stateEntry.getKey();
			Object value = stateEntry.getValue();
			outputStateObject(key, value);
		}
	}

	/**
	 * Writes a single state object to the output file.
	 * 
	 * @param key
	 * @param value
	 */
	@SuppressWarnings("unchecked")
	private void outputStateObject(String key, Object value)
	{
		if(value instanceof String) {
			_output.println("<" + key + ">" + value + "</" + key + ">");
		} else if(value instanceof Map<?,?>) {
			_output.println("<" + key + ">");
			// unchecked cast.. better ideas?
			writeStateObjects((Map<String, Object>) value);
			_output.println("</" + key + ">");
		} else if(value instanceof Iterable<?>) {
			Iterable<?> setValue = (Iterable<?>) value;
			for(Object subObject : setValue) {
				outputStateObject(key, subObject);
			}
		} else {
			throw new RuntimeException("Illegal state object passed to outputStateObject: " + key + ", " + value);
		}
	}

	public void close() {
		_output.print("</gamestate>");
		_output.close();

		try {
			Scanner scanner = new Scanner(new BufferedInputStream(_context.openFileInput("gamestate")));
			while(scanner.hasNext()) {
				Log.d("line", scanner.nextLine());
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
